package com.hdoit.ares.logical.acc.service.impl;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.hdoit.ares.logical.acc.dao.IWithdrawApplyforDao;
import com.hdoit.ares.logical.acc.model.AccountDetail;
import com.hdoit.ares.logical.acc.model.AccountInfo;
import com.hdoit.ares.logical.acc.model.WithdrawApplyfor;
import com.hdoit.ares.logical.acc.model.WithdrawParam;
import com.hdoit.ares.logical.acc.model.WithdrawRecord;
import com.hdoit.ares.logical.acc.service.IAccountDetailService;
import com.hdoit.ares.logical.acc.service.IAccountInfoService;
import com.hdoit.ares.logical.acc.service.IGoldenBeanDetailService;
import com.hdoit.ares.logical.acc.service.IIncomeTaxService;
import com.hdoit.ares.logical.acc.service.IWithdrawApplyforService;
import com.hdoit.ares.logical.acc.service.IWithdrawParamService;
import com.hdoit.ares.logical.acc.service.IWithdrawRecordService;
import com.hdoit.ares.logical.cust.model.Customer;
import com.hdoit.ares.logical.cust.service.ICustomerService;
import com.hdoit.ares.logical.viewmodel.acc.Withdraw;
import com.hdoit.ares.logical.viewmodel.acc.WithdrawApplyforSearch;
import com.hdoit.ares.selfcommon.enums.acc.ApplyforType;
import com.hdoit.ares.selfcommon.enums.acc.MoneyType;
import com.hdoit.ares.selfcommon.enums.acc.State;
import com.hdoit.ares.selfcommon.enums.acc.TrackType;
import com.tennetcn.common.dao.base.impl.SuperService;
import com.tennetcn.common.enums.ModelStatus;
import com.tennetcn.common.enums.pub.YesOrNo;
import com.tennetcn.common.logical.setting.dao.IParamOptionDao;
import com.tennetcn.common.message.LoginModel;
import com.tennetcn.common.message.PagerModel;
import com.tennetcn.common.utils.CommonUtils;
import com.tennetcn.common.utils.DateUtils;
import com.tennetcn.common.utils.RandomUtils;

/**
 * @author      caochengmeng
 * @email       
 * @createtime  2017年11月20日 16:32:40
 * @comment
 */
@Component
public class WithdrawApplyforServiceImpl extends SuperService<WithdrawApplyfor> implements IWithdrawApplyforService{
	
	private final static String StrOrderNum="yyMMddHHmmss";
	
	private IAccountDetailService accountDetailService;
	
	public IAccountDetailService getAccountDetailService() {
		return accountDetailService;
	}
	@Resource
	public void setAccountDetailService(IAccountDetailService accountDetailService) {
		this.accountDetailService = accountDetailService;
	}
	
	
	private IAccountInfoService accountInfoService;
	
	public IAccountInfoService getAccountInfoService() {
		return accountInfoService;
	}
	
	@Resource
	public void setAccountInfoService(IAccountInfoService accountInfoService) {
		this.accountInfoService = accountInfoService;
	}
	
	
	private IWithdrawApplyforService withdrawApplyforService;
	
	public IWithdrawApplyforService getWithdrawApplyforService() {
		return withdrawApplyforService;
	}
	
	@Resource
	public void setWithdrawApplyforService(IWithdrawApplyforService withdrawApplyforService) {
		this.withdrawApplyforService = withdrawApplyforService;
	}

	private IWithdrawApplyforDao withdrawApplyforDao;
	  
	public IWithdrawApplyforDao getWithdrawApplyforDao() {
		return withdrawApplyforDao;
	}
    
	@Resource
	public void setWithdrawApplyforDao(IWithdrawApplyforDao withdrawApplyforDao) {
		this.withdrawApplyforDao = withdrawApplyforDao;
	}
	
	private IWithdrawRecordService withdrawRecordService;
	public IWithdrawRecordService getWithdrawRecordService() {
		return withdrawRecordService;
	}
    
	@Resource
	public void setWithdrawRecordService(IWithdrawRecordService withdrawRecordService) {
		this.withdrawRecordService = withdrawRecordService;
	}
	
	private IGoldenBeanDetailService goldenBeanDetailService;
	public IGoldenBeanDetailService getGoldenBeanDetailService() {
		return goldenBeanDetailService;
	}
    @Resource
	public void setGoldenBeanDetailService(IGoldenBeanDetailService goldenBeanDetailService) {
		this.goldenBeanDetailService = goldenBeanDetailService;
	}
    
    private ICustomerService customerService;
	public ICustomerService getCustomerService() {
		return customerService;
	}
	@Resource
	public void setCustomerService(ICustomerService customerService) {
		this.customerService = customerService;
	}
	
    
	private IParamOptionDao paramOptionDao;

	public IParamOptionDao getParamOptionDao() {
		return paramOptionDao;
	}
	@Resource
	public void setParamOptionDao(IParamOptionDao paramOptionDao) {
		this.paramOptionDao = paramOptionDao;
	}
     
	private IWithdrawParamService withdrawParamService;

	public IWithdrawParamService getWithdrawParamService() {
		return withdrawParamService;
	}
	@Resource
	public void setWithdrawParamService(IWithdrawParamService withdrawParamService) {
		this.withdrawParamService = withdrawParamService;
	}
	
	private IIncomeTaxService incomeTaxService;
	public IIncomeTaxService getIncomeTaxService() {
		return incomeTaxService;
	}
	@Resource
	public void setIncomeTaxService(IIncomeTaxService incomeTaxService) {
		this.incomeTaxService = incomeTaxService;
	}
	
	@Override
	public List<WithdrawApplyfor> queryList(WithdrawApplyforSearch withdrawApplyforSearch, PagerModel pagerModel) {
		return withdrawApplyforDao.queryList(withdrawApplyforSearch,pagerModel);
	}

	@Override
	public List<WithdrawApplyfor> queryList(WithdrawApplyforSearch withdrawApplyforSearch) {
		return withdrawApplyforDao.queryList(withdrawApplyforSearch);
	}

	@Override
	public int queryCount(WithdrawApplyforSearch withdrawApplyforSearch) {
		return withdrawApplyforDao.queryCount(withdrawApplyforSearch);
	}
	
	
	@Override
	public List<WithdrawApplyfor> queryUnderwayWithdraw(String customerId, String state) {
		
		return withdrawApplyforDao.queryUnderwayWithdraw(customerId, state);
	}

	@Override
	public List<WithdrawApplyfor> queryFinishedWithdraw(String customerId, String state) {
		return withdrawApplyforDao.queryFinishedWithdraw(customerId, state);
	}
	
	
	
	
	public String toWithDrawApplyfor(Customer customer,Double money) {
		AccountInfo accountInfo1 = null;
  		accountInfo1 = accountInfoService.queryModelByCustomerId(customer.getId());
		
  		//第一步:产生一条提现记录
  		WithdrawRecord withdrawRecord = new WithdrawRecord();
		withdrawRecord.setId(CommonUtils.getKeyId());
		withdrawRecord.setState(TrackType.unTrack);
		withdrawRecord.setModelStatus(ModelStatus.add);
	
		
		//第二步:产生一条提现申请记录
		WithdrawApplyfor withdrawApplyfor = new WithdrawApplyfor();
		withdrawApplyfor.setId(CommonUtils.getKeyId());
		withdrawApplyfor.setName(customer.getUsername());
		withdrawApplyfor.setAid(withdrawRecord.getId());
		withdrawApplyfor.setAccountNo(accountInfo1.getAccountNo());
		withdrawApplyfor.setGoldBeanNum(Double.valueOf(money));
		withdrawApplyfor.setState(ApplyforType.applyWithdraw);
		withdrawApplyfor.setCreateDate(DateUtils.getCurrent());
		withdrawApplyfor.setDeleteMark(YesOrNo.no);
		withdrawApplyfor.setModelStatus(ModelStatus.add);
		withdrawApplyfor.setTrackState(withdrawRecord.getState());
		withdrawApplyfor.setOrderNum("putianwit"+DateUtils.convertDate2String(StrOrderNum,
				DateUtils.getCurrent())+RandomUtils.randomInt(1000, 9999));
		withdrawApplyfor.setCustomerId(String.valueOf(customer.getId()));
		withdrawApplyfor.setAccount(String.valueOf(customer.getUserIdentity()));
		
		//第三步:账户余额发生改变
		AccountInfo accountInfo = accountInfoService.queryModelByCustomerId(withdrawApplyfor.getCustomerId());
		accountInfo.setBalance(accountInfo.getBalance() - withdrawApplyfor.getGoldBeanNum());
		accountInfo.setModelStatus(ModelStatus.update);
		
		
		//第四步:产生余额明细记录
	    AccountDetail accountDetail = new AccountDetail();
	    accountDetail.setId(CommonUtils.getKeyId());
	    accountDetail.setCustomerId(withdrawApplyfor.getCustomerId());
	    accountDetail.setAccountNo(accountInfo.getAccountNo());
	    accountDetail.setMoneyType(MoneyType.applyfor);
	    accountDetail.setState(State.pay);
	    accountDetail.setServiceId(withdrawApplyfor.getOrderNum());
	    accountDetail.setTime(DateUtils.getCurrent());
	    accountDetail.setMoney(money);
	    accountDetail.setBalance(accountInfo.getBalance());
	    accountDetail.setModelStatus(ModelStatus.add);
	    

		
		//第五步:返回提现请求结果
		if(withdrawApplyforService.applyChange(withdrawApplyfor) && withdrawRecordService.applyChange(withdrawRecord) && accountInfoService.applyChange(accountInfo) && accountDetailService.applyChange(accountDetail)){
			return withdrawApplyfor.getId();
		}
		
		return null;
	}



	
	@Override
	public boolean updateGoldBeanNum(Withdraw withdraw, LoginModel loginModel) {
		      
		
		        //第一步:提现申请表中状态值发生改变
				WithdrawApplyfor withdrawApplyfor = withdrawApplyforUtil(withdraw.getWithdrawApplyforId());
                
				
				//第二步:提现记录表中数据修改
				WithdrawRecord withdrawRecord = withdrawRecordUtil(withdrawApplyfor.getAid(),loginModel);
				
				//AccountInfo accountInfo = accountInfoService.queryModelByCustomerId(withdrawApplyfor.getCustomerId());
				
				//第三步:余额明细添加记录
				AccountDetail accountDetail = accountDetailService.queryModelByServiceId(withdrawApplyfor.getOrderNum());
			    accountDetail.setMoneyType(MoneyType.toBalance);
			    accountDetail.setTime(DateUtils.getCurrent());
			    accountDetail.setModelStatus(ModelStatus.update);
			    

				 

				return (withdrawApplyforService.applyChange(withdrawApplyfor) && withdrawRecordService.applyChange(withdrawRecord) && accountDetailService.applyChange(accountDetail));

	}
	@Override
	public Withdraw updateToConfirm(String key) {
		WithdrawApplyfor withdrawApplyfor = withdrawApplyforService.queryModel(key);
		//确保是否提现过,如果已经提现则操作无效
		if(ApplyforType.accountWithdraw.equals(withdrawApplyfor.getState())){
			return null;
		}
		//金豆兑换钱的比例。100:1.
		/*ParamOption paramOption = paramOptionDao.queryModelByParamName("exchange");
		int exchangeRate = Integer.valueOf(paramOption.getParamValue());*/
        //得到提现金额，单位是分
		double goldBean = withdrawApplyfor.getGoldBeanNum() ;
		Integer amount = new BigDecimal(String.valueOf(incomeTaxService.queryNetSalary(goldBean,withdrawApplyfor.getCustomerId()))).setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue();
		
		Customer customer = customerService.queryModel(withdrawApplyfor.getCustomerId());		
	    Withdraw withdraw = new Withdraw();
	    withdraw.setAmount(amount);
	    withdraw.setOpenId(customer.getOpenId());
	    withdraw.setAppOpenId(customer.getAppOpenId());
	    withdraw.setWithdrawApplyforId(key);
	    return withdraw;
	}
	
	
	//提取公共代码，用于提现
	public WithdrawApplyfor withdrawApplyforUtil(String key){
		WithdrawApplyfor withdrawApplyfor = withdrawApplyforService.queryModel(key);
		withdrawApplyfor.setState(ApplyforType.accountWithdraw);
		withdrawApplyfor.setModelStatus(ModelStatus.update);
		
		return withdrawApplyfor;
	}
	
	public WithdrawRecord withdrawRecordUtil(String key,LoginModel loginModel){
		WithdrawRecord withdrawRecord = withdrawRecordService.queryModel(key);
		withdrawRecord.setState(TrackType.tracked);
		withdrawRecord.setModifyDate(DateUtils.getCurrent());
		
		if(loginModel != null){
		   withdrawRecord.setModifyUserId(loginModel.getLoginId());
		   withdrawRecord.setModifyUserName(loginModel.getLoginName());
		}
		
		 withdrawRecord.setModelStatus(ModelStatus.update);
		
		return withdrawRecord;
	}
	
	
	@Override
	public boolean updateForRollBack(Withdraw withdraw, LoginModel loginModel) {
		 //第一步:提现申请表中状态值发生改变
		WithdrawApplyfor withdrawApplyfor = withdrawApplyforUtil(withdraw.getWithdrawApplyforId());

		//第二步:提现记录表中数据修改
		WithdrawRecord withdrawRecord = withdrawRecordUtil(withdrawApplyfor.getAid(),loginModel);
		
		//第三步:账户余额发生变化
		AccountInfo accountInfo = accountInfoService.queryModelByCustomerId(withdrawApplyfor.getCustomerId());
		accountInfo.setBalance(accountInfo.getBalance() + withdrawApplyfor.getGoldBeanNum());
		accountInfo.setModelStatus(ModelStatus.update);
	   
	    //第四步:余额明细添加记录
		AccountDetail accountDetail = new AccountDetail();
	    accountDetail.setId(CommonUtils.getKeyId());
	    accountDetail.setCustomerId(withdrawApplyfor.getCustomerId());
	    accountDetail.setAccountNo(accountInfo.getAccountNo());
	    accountDetail.setMoneyType(MoneyType.refund);
	    accountDetail.setState(State.income);
	    accountDetail.setServiceId(withdraw.getOutTradeNo());
	    accountDetail.setTime(DateUtils.getCurrent());
	    accountDetail.setMoney(withdrawApplyfor.getGoldBeanNum());
	    accountDetail.setBalance(accountInfo.getBalance());
	    accountDetail.setModelStatus(ModelStatus.add);
		
	   
	    return (withdrawApplyforService.applyChange(withdrawApplyfor) && withdrawRecordService.applyChange(withdrawRecord) && accountDetailService.applyChange(accountDetail) && accountInfoService.applyChange(accountInfo));
	}
	
	/**
	 *第一版本提现是纯人工审核   2017/12/26前
	 *第二版本提现是额度限制 半人工     2017/12/26日起
	 *
	 */
	@Override
	public HashMap<String, String> applyLimit(Customer customer, Double money) {
		//得到一天的起始时间
		Calendar calendar1 = Calendar.getInstance();  
        calendar1.set(calendar1.get(Calendar.YEAR), calendar1.get(Calendar.MONTH), calendar1.get(Calendar.DAY_OF_MONTH),  
                0, 0, 0);  
        Date beginOfDate = calendar1.getTime();  
        System.out.println(beginOfDate);  
        
        //得到一天的终止时间
        Calendar calendar2 = Calendar.getInstance();  
        calendar1.set(calendar2.get(Calendar.YEAR), calendar2.get(Calendar.MONTH), calendar2.get(Calendar.DAY_OF_MONTH),  
                23, 59, 59);  
        Date endOfDate = calendar1.getTime();  
        System.out.println(endOfDate); 
		
        //通过起始时间、终止时间和customerId去查询提现记录中的总笔数和日提现总金额
        AccountDetail accountDetail = accountDetailService.queryAccountDetailByTime(customer.getId(), beginOfDate, endOfDate);
        int sumNum = accountDetail.getTotalNum();
        double sumMoney = accountDetail.getTotalMoney();
        
        //将限额参数全部查询出来
        WithdrawParam minLimit  = withdrawParamService.queryModelByHelpCode("minLimit");
        WithdrawParam perLimit  = withdrawParamService.queryModelByHelpCode("perLimit");
        WithdrawParam withdrawCount  = withdrawParamService.queryModelByHelpCode("withdrawCount");
        WithdrawParam totalMoney  = withdrawParamService.queryModelByHelpCode("totalMoney");
        AccountInfo accountInfo  = accountInfoService.queryModelByCustomerId(customer.getId());
        
        
        HashMap<String,String> result = new HashMap<String, String>();
        
        if(money > accountInfo.getBalance() || money <= 0){
        	result.put("result", "false");
        	result.put("message", "提现金额数目有误！");
        	
        	return result;
        }
        
        
        //开始进行流程判断
        if(sumNum < withdrawCount.getParam()){
        	
        	if(money <= perLimit.getParam()){
        		
        	     if(sumMoney + money <= totalMoney.getParam()){
        	    	  String key = toWithDrawApplyfor(customer,money);
        	    	  if(!StringUtils.isEmpty(key)){
        	    		  
        	    		  if(money <= minLimit.getParam()){
        	    			  result.put("message", "pass");
        	    			  result.put("key", key);
        	    		  }else{
        	    			  result.put("key","check");
        	    			  result.put("message", "亲，超过免审额度" + minLimit.getParam() + "元限制了哦,后台小哥正在审核");
        	    		  }
        	    	  result.put("result", "true");
        	    	  return result;
        	    	  }else{
        	    		  result.put("message", "亲，系统发生错误，开发小哥正在排查");
        	    	  }
        	    	 
        	     }else{
        	    	 result.put("message", "亲，已超过日提现额度" + totalMoney.getParam() + "元限制了哦！");
        	     }
        	     
        	}else{
        		result.put("message", "亲，已超过每笔提现额度" + perLimit.getParam() + "元限制了哦！");
        	}
        	
        }else{
        	result.put("message", "亲，已超过日提现笔数" + withdrawCount.getParam() + "次限制了哦！");
        }
       
        System.err.println(result.get("message"));
       
        result.put("result","false");
        return result;
	}
   
}
